<template>
  <div class="goods-sku">
    <dl v-for="(item,index) in specs" :key="index">
      <dt>{{item.name}}</dt>
      <dd>
        <template v-for="(tag,index) in item.values" :key="index">
            <img @click="toggle(tag, item.values)" :class="{selected:tag.selected,disabled:tag.disabled}" v-if="tag.picture" :src="tag.picture" >
            <span v-else @click="toggle(tag, item.values)" :class="{selected:tag.selected,disabled:tag.disabled}" >{{tag.name}}</span>
        </template>
      </dd>
    </dl>
  </div>
</template>
<script>
import powerSet from '@/vendor/power-set.js'
const spliter = '※'
// 生成路径字典
const usePathMap = (skus) => {
  // 路径字典结果
  const pathMap = {}
  skus.forEach(sku => {
    if (sku.inventory === 0) return
    // 获取规格的集合数据：skuSpec=[蓝色，中国，10cm]
    const skuSpec = sku.specs.map(tag => tag.valueName)
    const specSet = powerSet(skuSpec)
    // 计算sku规则组合的笛卡尔集
    specSet.forEach(spec => {
      if (spec.length === 0) return
      const mapKey = spec.join(spliter)
      if (pathMap[mapKey]) {
        pathMap[mapKey].push(sku.id)
      } else {
        pathMap[mapKey] = [sku.id]
      }
    })
  })
  return pathMap
}
// 获获取选中值
const getSelectedValues = (specs) => {
  const result = []
  specs.forEach((item, index) => {
    const tag = item.values.find(tag => tag.selected)
    if (tag) {
      result[index] = tag.name
    } else {
      result[index] = undefined
    }
  })
  return result
}
// 控制选中规则切换
const updateDisabledStatus = (specs, pathMap) => {
  specs.forEach((item, index) => {
    const selectedValues = getSelectedValues(specs)
    item.values.forEach(tag => {
      if (tag.selected) {
        return
      } else {
        //  模拟选中一个值
        selectedValues[index] = tag.name
      }
      const pathKey = selectedValues.filter(item => item).join(spliter)
      tag.disabled = !pathMap[pathKey]
    })
  })
}
// 根据skuId控制规格选中
const initSkuIdSelected = (skuId, specs, skus) => {
  const target = skus.find(item => item.id === skuId).specs
  specs.forEach(item => {
    const currentSpec = target.find(tag => tag.name === item.name)
    item.values.forEach(tag => {
      if (tag.name === currentSpec.valueName) {
        tag.selected = true
      }
    })
  })
}

export default {
  name: 'GoodsSku',
  emits: ['sku-info'],
  props: {
    specs: {
      type: Array,
      default: () => []
    },
    skus: {
      type: Array,
      default: () => []
    },
    skuId: {
      type: String,
      default: ''
    }
  },
  setup (props, { emit }) {
    const pathMap = usePathMap(props.skus)
    updateDisabledStatus(props.specs, pathMap)
    if (props.skuId) {
      initSkuIdSelected(props.skuId, props.specs, props.skus)
    }
    const toggle = (tag, list) => {
      if (tag.disabled) return
      list.forEach((item) => {
        if (item !== tag) { item.selected = false }
      })
      tag.selected = !tag.selected
      updateDisabledStatus(props.specs, pathMap)
      //   判断是否选中了所有规格
      const selectedValues = getSelectedValues(props.specs)
      if (selectedValues.filter(item => item).length === props.specs.length) {
        const pathKey = selectedValues.filter(item => item).join(spliter)
        const skuId = pathMap[pathKey][0]
        const skuInfo = props.skus.find(item => item.id === skuId)
        const goodsInfo = {
          skuId: skuId,
          oldPrice: skuInfo.oldPrice,
          price: skuInfo.price,
          specText: skuInfo.specs.reduce((result, item) => result + item.name + ':' + item.valueName + '', '')
        }
        // 把商品信息传递到父组件
        emit('sku-info', goodsInfo)
      }
    }

    return { toggle }
  }
}
</script>
<style scoped lang="less">
.sku-state-mixin () {
  border: 1px solid #e4e4e4;
  margin-right: 10px;
  cursor: pointer;
  &.selected {
    border-color: @xtxColor;
  }
  &.disabled {
    opacity: 0.6;
    border-style: dashed;
    cursor: not-allowed;
  }
}
.goods-sku {
  padding-left: 10px;
  padding-top: 20px;
  dl {
    display: flex;
    padding-bottom: 20px;
    align-items: center;
    dt {
      width: 50px;
      color: #999;
    }
    dd {
      flex: 1;
      color: #666;
      > img {
        width: 50px;
        height: 50px;
        .sku-state-mixin ();
      }
      > span {
        display: inline-block;
        height: 30px;
        line-height: 28px;
        padding: 0 20px;
        .sku-state-mixin ();
      }
    }
  }
}
</style>
